export const MONTH_MAP_ARRAY = [null, "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
export const oneOrTwoDigitsReg = /^0*\d\d?$/;
export const NUMBER_MAP_CHINESE = ['',
  '一', '二', '三', '四', '五', '六', '七', '八', '九',
  '十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九',
  '二十', '二十一', '二十二', '二十三', '二十四', '二十五', '二十六', '二十七', '二十八', '二十九',
  '三十', '三十一', '三十三', '三十三', '三十四', '三十五', '三十六', '三十七', '三十八', '三十九',
]

const y = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];

export abstract class Describer {
  private readonly patternHandles: ReadonlyArray<(exp: string) => string>;

  public constructor(readonly description: string) {
    this.patternHandles = [
      this.starSegment,
      this.singleNumberSegment,
      this.starSlashNumberSegment,
      this.spanSegment,
      this.spanSlashNumberSegment
    ]
  }

  parseSpan(exp: String) {
    const [_, start, end] = exp.match(/^(\d+)-(\d+)$/)
    return {start, end}
  }

  parseSpanSlashNumber(exp: string) {
    const [_, start, end, interval] = exp.match(/^(\d+)-(\d+)\/(\d+)$/)
    return {start, end, interval}
  }


  // ['*','3','*/3',1-2,1-9/3]
  toPatternIndex(exp: string): 0 | 1 | 2 | 3 | 4 {
    if (exp === '*') {
      return 0
    }

    if (!isNaN(Number(exp))) {
      return 1
    }

    if (exp.startsWith(`*/`) && this.isNumber(exp.replace(`*/`, ''))) {
      return 2
    }

    if (exp.match(/^\d+-\d+$/)) {
      return 3
    }

    if (exp.match(/^\d+-\d+\/\d+$/)) {
      return 4
    }
  }


  private isNumber(str: string): boolean {
    const num = Number(str)
    return !isNaN(num)
  }

  private segmentDesc(segmentExp: string): string {
    const index = this.toPatternIndex(segmentExp)
    return this.patternHandles[index](segmentExp)
  }

  describe() {
    const segmentDescriptions = this.description
      .split(",")
      .map(exp => {
        return this.segmentDesc(exp);
      })

    return (function (e) {
      switch (e.length) {
        case 0:
          return "";

        case 1:
          return e[0];

        case 2:
          return e[0] + "和" + e[1];

        default:
          return e.slice(0, e.length - 1).join(",") + "和" + e[e.length - 1];
      }
    }(segmentDescriptions))
    // .replace("every 1st", "every")
    // .replace(meaning + " every", "every")
    // .replace(", " + meaning, ", ")
    // .replace(", and " + meaning, ", and ");
  }


  abstract starSegment(exp: string): string

  abstract singleNumberSegment(exp: string): string

  abstract starSlashNumberSegment(exp: string): string

  abstract spanSegment(exp: string): string

  abstract spanSlashNumberSegment(exp: string): string
}
